home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / sbin / update-grub < prev    next >
Encoding:
Text File  |  2009-04-08  |  41.8 KB  |  1,556 lines

  1. #!/bin/bash
  2. #
  3. # Insert a list of installed kernels in a grub config file
  4. #   Copyright 2001 Wichert Akkerman <wichert@linux.com>
  5. #   Copyright 2007, 2008 Canonical Ltd.
  6. #
  7. # This file is free software; you can redistribute it and/or modify it
  8. # under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful, but
  13. # WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. # General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. #
  21. # Contributors:
  22. #    Jason Thomas <jason@debian.org>
  23. #    David B.Harris <dbarclay10@yahoo.ca>
  24. #    Marc Haber <mh@zugschlus.de>
  25. #    Crispin Flowerday <crispin@zeus.com>
  26. #    Steve Langasek <steve.langasek@canonical.com>
  27.  
  28. # Abort on errors
  29. set -e
  30.  
  31. # load debconf first, since this re-execs the script
  32. . /usr/share/debconf/confmodule
  33.  
  34. host_os=`uname -s | tr '[A-Z]' '[a-z]'`
  35.  
  36. abort() {
  37.     message=$@
  38.  
  39.     echo >&2
  40.     printf '%s\n' "$message" >&2
  41.     echo >&2
  42.     exit 1
  43. }
  44.  
  45. find_grub_dir ()
  46. {
  47.     echo  -n "Searching for GRUB installation directory ... " >&2
  48.  
  49.     for d in $grub_dirs ; do
  50.         if [ -d "$d" ] ; then
  51.             grub_dir="$d"
  52.             break
  53.         fi
  54.     done
  55.     
  56.     if [ -z "$grub_dir" ] ; then
  57.         abort "No GRUB directory found.
  58.  To create a template run 'mkdir /boot/grub' first.
  59.  To install grub, install it manually or try the 'grub-install' command.
  60.  ### Warning, grub-install is used to change your MBR. ###"
  61.     else
  62.         echo "found: $grub_dir" >&2
  63.     fi
  64.  
  65.     echo $grub_dir
  66. }
  67.  
  68. find_device ()
  69. {
  70.     mount_point=$1
  71.  
  72.     # Autodetect current root device
  73.     device=
  74.     if [ -f /etc/fstab ] ; then
  75.         device=$(awk '$1!~/^#/{
  76.           if ($2 ~ "^/+$") { $2 = "/"; } else { sub("/*$", "", $2); }
  77.           if ($2 == "'"$mount_point"'"){
  78.                 print $1;
  79.             }
  80.           }' /etc/fstab | tail -n 1)
  81.     fi
  82.  
  83.     if [ -n "$device" ] ; then
  84.         case "$device" in
  85.             LABEL=* | UUID=*)
  86.                 device=`readlink -f "$(findfs $device)"`
  87.             ;;
  88.             *)
  89.                 device=`readlink -f "$device"`
  90.             ;;
  91.         esac
  92.     fi
  93.  
  94.     echo $device
  95. }
  96.  
  97. find_root_device ()
  98. {
  99.     device=$(find_device "/")
  100.  
  101.     if [ -z "$device" ]; then
  102.         echo "Cannot determine root device.  Assuming /dev/hda1" >&2
  103.         echo "This error is probably caused by an invalid /etc/fstab" >&2
  104.         device=/dev/hda1
  105.     fi
  106.  
  107.     echo $device
  108. }
  109.  
  110. # Usage: convert_raid1 os_device
  111. # Checks if os_device is a software raid1.
  112. # If so, converts to first physical device in array.
  113. convert_raid1 ()
  114. {
  115.     case $1 in
  116.         /dev/md[0-9])
  117.             : ;; # Continue
  118.         *)
  119.             return 1 ;;
  120.     esac
  121.  
  122.     [ -x /sbin/mdadm ] || return 1
  123.  
  124.     # Check that the raid device is raid1
  125.     raidlevel=$(mdadm -D -b $1 | grep "^ARRAY" | \
  126.             sed "s/^.*level=//" | cut -d" " -f1)
  127.     [ "$raidlevel" = "raid1" ] || return 1
  128.     
  129.     # Take only the first device that makes up the raid
  130.     raiddev=$(mdadm -D $1 | grep -A1 "Number" | grep "dev" \
  131.                           | sed "s/^.*\(\/dev\/.*\)$/\1/")
  132.     [ -n "$raiddev" ] || return 1
  133.  
  134.     echo $raiddev
  135.     return 0
  136. }
  137.  
  138. # Usage: convert os_device
  139. # Convert an OS device to the corresponding GRUB drive.
  140. # This part is OS-specific.
  141. convert () {
  142.     # First, check if the device file exists.
  143.     if test -e "$1"; then
  144.         :
  145.     else
  146.         echo "$1: Not found or not a block device." 1>&2
  147.         exit 1
  148.     fi
  149.  
  150.     host_os=`uname -s | tr '[[:upper:]]' '[[:lower:]]'`
  151.  
  152.     # Break the device name into the disk part and the partition part.
  153.     case "$host_os" in
  154.     linux)
  155.         tmp_disk=`echo "$1" | sed -e 's%\([sh]d[[:lower:]]\)[0-9]*$%\1%' \
  156.                   -e 's%\(fd[0-9]*\)$%\1%' \
  157.                   -e 's%/part[0-9]*$%/disc%' \
  158.                   -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
  159.         tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[[:lower:]]\([0-9]*\)$%\1%' \
  160.                   -e 's%.*/fd[0-9]*$%%' \
  161.                   -e 's%.*/floppy/[0-9]*$%%' \
  162.                   -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
  163.                   -e 's%.*c[0-7]d[0-9]*p*%%'`
  164.     ;;
  165.     gnu)
  166.         tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
  167.         tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
  168.     freebsd|*/kfreebsd)
  169.         tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
  170.                 | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
  171.         tmp_part=`echo "$1" \
  172.                 | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
  173.                    | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
  174.     ;;
  175.     netbsd|*/knetbsd)
  176.         tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
  177.                 | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
  178.         tmp_part=`echo "$1" \
  179.                 | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
  180.     ;;
  181.     *)
  182.         echo "update-grub does not support your OS yet." 1>&2
  183.         exit 1 ;;
  184.     esac
  185.  
  186.     # Get the drive name.
  187.     tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
  188.             | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
  189.  
  190.     # If not found, print an error message and exit.
  191.     if test "x$tmp_drive" = x; then
  192.         echo "$1 does not have any corresponding BIOS drive." 1>&2
  193.         exit 1
  194.     fi
  195.  
  196.     if test "x$tmp_part" != x; then
  197.         # If a partition is specified, we need to translate it into the
  198.         # GRUB's syntax.
  199.         case "$host_os" in
  200.         linux)
  201.               echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
  202.         gnu)
  203.               if echo $tmp_part | grep "^s" >/dev/null; then
  204.                 tmp_pc_slice=`echo $tmp_part \
  205.                     | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
  206.                 tmp_drive=`echo "$tmp_drive" \
  207.                     | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
  208.               fi
  209.               if echo $tmp_part | grep "[a-z]$" >/dev/null; then
  210.                 tmp_bsd_partition=`echo "$tmp_part" \
  211.                     | sed "s%[^a-z]*\([a-z]\)$%\1%"`
  212.                 tmp_drive=`echo "$tmp_drive" \
  213.                     | sed "s%)%,$tmp_bsd_partition)%"`
  214.               fi
  215.               echo "$tmp_drive" ;;
  216.         freebsd|*/kfreebsd)
  217.               if echo $tmp_part | grep "^s" >/dev/null; then
  218.                 tmp_pc_slice=`echo $tmp_part \
  219.                     | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
  220.                 tmp_drive=`echo "$tmp_drive" \
  221.                     | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
  222.               fi
  223.               if echo $tmp_part | grep "[a-h]$" >/dev/null; then
  224.                 tmp_bsd_partition=`echo "$tmp_part" \
  225.                     | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
  226.                 tmp_drive=`echo "$tmp_drive" \
  227.                     | sed "s%)%,$tmp_bsd_partition)%"`
  228.               fi
  229.               echo "$tmp_drive" ;;
  230.         netbsd|*/knetbsd)
  231.               if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
  232.                 tmp_bsd_partition=`echo "$tmp_part" \
  233.                     | sed "s%\([a-p]\)$%\1%"`
  234.                 tmp_drive=`echo "$tmp_drive" \
  235.                     | sed "s%)%,$tmp_bsd_partition)%"`
  236.               fi
  237.               echo "$tmp_drive" ;;
  238.         esac
  239.     else
  240.         # If no partition is specified, just print the drive name.
  241.         echo "$tmp_drive"
  242.     fi
  243. }
  244.  
  245. # Usage: convert_default os_device
  246. # Convert an OS device to the corresponding GRUB drive.
  247. # Calls OS-specific convert, and returns a default of
  248. # (hd0,0) if anything goes wrong
  249. convert_default () {
  250.     # Check if device is software raid1 array
  251.     if tmp_dev=$(convert_raid1 $1 2>/dev/null) ; then
  252.         : # Use device returned by convert_raid1
  253.     else
  254.         tmp_dev=$1
  255.     fi
  256.  
  257.     if tmp=$(convert $tmp_dev 2>/dev/null) ; then
  258.         echo $tmp
  259.     else
  260.         echo "(hd0,0)"
  261.     fi
  262. }
  263.  
  264. is_removable () {
  265.     removabledevice="$(echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' -e 's%\(fd[0-9]*\)$%\1%' -e 's%/part[0-9]*$%/disc%' -e 's%\(c[0-7]d[0-9]*\).*$%\1%' -e 's%^/dev/%%g')"
  266.         if [ -e "/sys/block/$removabledevice/removable" ]; then
  267.                 if [ "$(cat /sys/block/$removabledevice/removable)" != "0" ]; then
  268.                         echo "/dev/$removabledevice"
  269.                         return
  270.                 fi
  271.         fi
  272.     echo ""
  273. }
  274.  
  275. convert_to_uuid()
  276. {
  277.     local dev; dev=$1
  278.  
  279.     convert=false
  280.     case "$dev" in
  281.         /dev/disk/*)
  282.             ;;
  283.         /dev/mapper/*)
  284.             ;;
  285.         /dev/evms/[hs]d[a-z][0-9]*)
  286.             convert=:
  287.             ;;
  288.         /dev/evms/*)
  289.             ;;
  290.         /dev/md[0-9]*)
  291.             ;;
  292.         /dev/*)
  293.             convert=:
  294.             ;;
  295.     esac
  296.     if $convert; then
  297.         if [ -b "$dev" ]; then
  298.             uuid=$(/sbin/vol_id -u "$dev" || true)
  299.         fi
  300.     fi
  301.  
  302.     echo "$uuid"
  303. }
  304.  
  305. convert_kopt_to_uuid()
  306. {
  307.     local kopt; kopt=$1
  308.  
  309.     convert=false
  310.     root=$(echo "$kopt" | sed 's/.*root=//;s/ .*//')
  311.     case "$root" in
  312.         UUID=*|LABEL=*)
  313.             ;;
  314.         /dev/disk/*)
  315.             ;;
  316.         /dev/mapper/*)
  317.             ;;
  318.         /dev/evms/[hs]d[a-z][0-9]*)
  319.             convert=:
  320.             ;;
  321.         /dev/evms/*)
  322.             ;;
  323.         /dev/md[0-9]*)
  324.             ;;
  325.         /dev/*)
  326.             convert=:
  327.             ;;
  328.     esac
  329.     if $convert; then
  330.         if [ -L "$DEV" ] && readlink "$DEV" | grep -q "^/dev/mapper/"
  331.         then
  332.             :
  333.         elif [ -b "$root" ]; then
  334.             uuid=$(/sbin/vol_id -u "$root" || true)
  335.             if [ -n "$uuid" ]; then
  336.                 kopt=$(echo "$kopt" | sed "s/\(.*root=\)[^ ]*/\1UUID=$uuid/")
  337.             fi
  338.         fi
  339.     fi
  340.  
  341.     echo "$kopt"
  342. }
  343.  
  344.  
  345. ## Configuration Options
  346. # directory's to look for the grub installation and the menu file
  347. grub_dirs="/boot/grub /boot/boot/grub"
  348.  
  349. # The grub installation directory
  350. grub_dir=$(find_grub_dir)
  351.  
  352. # Full path to the menu.lst
  353. menu_file_basename=menu.lst
  354. menu_file=$grub_dir/$menu_file_basename
  355.  
  356. # Full path to the menu.lst fragment used for ucf management
  357. ucf_menu_file=/var/run/grub/$menu_file_basename
  358.  
  359. # Full path to the default file
  360. default_file_basename=default
  361. default_file=$grub_dir/$default_file_basename
  362.  
  363. # the device for the / filesystem
  364. root_device=$(find_root_device)
  365.  
  366. # the device for the /boot filesystem
  367. boot_device=$(find_device "/boot")
  368.  
  369. # Full path to the device.map
  370. device_map=$grub_dir/device.map
  371.  
  372. # Default kernel options, overidden by the kopt statement in the menufile.
  373. loop_file=$(awk '$2=="/" && $4~"loop" {print $1}' /etc/fstab)
  374. if [ -n "$loop_file" ]; then
  375.     dev_mountpoint=$(awk '"'${loop_file}'"~"^"$2 && $2!="/" {print $1";"$2}' /proc/mounts|tail -n 1)
  376.     host_device="${dev_mountpoint%;*}"
  377.     host_mountpoint="${dev_mountpoint#*;}"
  378. fi
  379. if [ -n "$host_device" ]; then
  380.     boot_device=
  381.     root_device="$host_device"
  382.     default_kopt="root=$host_device loop=${loop_file#$host_mountpoint} ro"
  383. else
  384.     default_kopt="root=$root_device ro"
  385. fi
  386. default_kopt="$(convert_kopt_to_uuid "$default_kopt")"
  387. kopt="$default_kopt"
  388.  
  389. # Title
  390. title=$(lsb_release --short --description 2>/dev/null) || title="Ubuntu"
  391.  
  392. # should update-grub remember the default entry
  393. updatedefaultentry="false"
  394.  
  395. # Drive(in GRUB terms) where the kernel is located. Overridden by the
  396. # kopt statement in menufile.
  397. # if we don't have a device.map then we can't use the convert function.
  398.  
  399. # Try to use a UUID instead of the GRUB device name.
  400. if test -z "$boot_device" ; then
  401.     uuid=$(convert_to_uuid "$root_device")
  402. else
  403.     uuid=$(convert_to_uuid "$boot_device")
  404. fi
  405.  
  406. if [ -n "$uuid" ]; then
  407.     grub_root_device="$uuid"
  408. fi
  409.  
  410. check_removable=""
  411. if test -z "$uuid"; then
  412.     if test -f "$device_map"; then
  413.         if test -z "$boot_device" ; then
  414.             grub_root_device=$(convert_default "$root_device")
  415.             check_removable="$(is_removable "$root_device")"
  416.         else
  417.             grub_root_device=$(convert_default "$boot_device")
  418.             check_removable="$(is_removable "$boot_device")"
  419.         fi
  420.     else
  421.         grub_root_device="(hd0,0)"
  422.     fi
  423. fi
  424.  
  425. # If the root/boot device is on a removable target, we need to override
  426. # the grub_root_device to (hd0,X). This is a requirement since the BIOS
  427. # will change device mapping dynamically if we switch boot device.
  428.  
  429. if test -n "$check_removable" ; then
  430.     grub_root_device="$(echo "$grub_root_device" | sed -e 's/d.*,/d0,/g')"
  431. fi
  432.  
  433. # should grub create the alternative boot options in the menu
  434.     alternative="true"
  435.  
  436. # should grub lock the alternative boot options in the menu
  437.     lockalternative="false"
  438.  
  439. # additional options to use with the default boot option, but not with the
  440. # alternatives
  441.     defoptions="quiet splash"
  442.  
  443. # should grub lock the old kernels
  444.     lockold="false"
  445.  
  446. # Xen hypervisor options to use with the default Xen boot option
  447.     xenhopt=""
  448.  
  449. # Xen Linux kernel options to use with the default Xen boot option
  450.     xenkopt="console=tty0"
  451.  
  452. # options to use with the alternative boot options
  453.     altoptions="(recovery mode) single"
  454.  
  455. # controls howmany kernels are listed in the config file,
  456. # this does not include the alternative kernels
  457.     howmany="all"
  458.  
  459. # should grub create a memtest86 entry
  460.     memtest86="true"
  461.  
  462. # should grub add "savedefault" to default boot options
  463.     savedefault="false"
  464.  
  465. # is grub running in a domU?
  466.     indomU="detect"
  467.  
  468. # stores the command line arguments
  469.     command_line_arguments=$1
  470.  
  471. # does this version of grub support the quiet option?
  472. if [ -f ${grub_dir}/installed-version ] && dpkg --compare-versions `cat ${grub_dir}/installed-version` ge 0.97-11ubuntu4; then
  473.     supports_quiet=true
  474. else
  475.     supports_quiet=false
  476. fi
  477.  
  478. # read user configuration
  479. if test -f "/etc/default/grub" ; then
  480.     . /etc/default/grub
  481. fi
  482.  
  483. # Default options to use in a new config file. This will only be used if $menu_file
  484. # doesn't already exist. Only edit the lines between the two "EOF"s. The others are
  485. # part of the script.
  486. newtemplate=$(tempfile)
  487. cat >> "$newtemplate" <<EOF
  488. # $menu_file_basename - See: grub(8), info grub, update-grub(8)
  489. #            grub-install(8), grub-floppy(8),
  490. #            grub-md5-crypt, /usr/share/doc/grub
  491. #            and /usr/share/doc/grub-doc/.
  492.  
  493. ## default num
  494. # Set the default entry to the entry number NUM. Numbering starts from 0, and
  495. # the entry number 0 is the default if the command is not used.
  496. #
  497. # You can specify 'saved' instead of a number. In this case, the default entry
  498. # is the entry saved with the command 'savedefault'.
  499. # WARNING: If you are using dmraid do not use 'savedefault' or your
  500. # array will desync and will not let you boot your system.
  501. default        0
  502.  
  503. ## timeout sec
  504. # Set a timeout, in SEC seconds, before automatically booting the default entry
  505. # (normally the first entry defined).
  506. timeout        3
  507.  
  508. ## hiddenmenu
  509. # Hides the menu by default (press ESC to see the menu)
  510. hiddenmenu
  511.  
  512. # Pretty colours
  513. #color cyan/blue white/blue
  514.  
  515. ## password ['--md5'] passwd
  516. # If used in the first section of a menu file, disable all interactive editing
  517. # control (menu entry editor and command-line)  and entries protected by the
  518. # command 'lock'
  519. # e.g. password topsecret
  520. #      password --md5 \$1\$gLhU0/\$aW78kHK1QfV3P2b2znUoe/
  521. # password topsecret
  522.  
  523. #
  524. # examples
  525. #
  526. # title        Windows 95/98/NT/2000
  527. # root        (hd0,0)
  528. # makeactive
  529. # chainloader    +1
  530. #
  531. # title        Linux
  532. # root        (hd0,1)
  533. # kernel    /vmlinuz root=/dev/hda2 ro
  534. #
  535.  
  536. #
  537. # Put static boot stanzas before and/or after AUTOMAGIC KERNEL LIST
  538.  
  539. EOF
  540. ## End Configuration Options
  541.  
  542. echo -n "Searching for default file ... " >&2
  543. if [ -f "$default_file" ] ; then
  544.   echo "found: $default_file" >&2
  545. else
  546.   echo "Generating $default_file file and setting the default boot entry to 0" >&2
  547.   grub-set-default 0
  548. fi
  549.  
  550. # Make sure we use the standard sorting order
  551. LC_COLLATE=C
  552. # Magic markers we use
  553. start="### BEGIN AUTOMAGIC KERNELS LIST"
  554. end="### END DEBIAN AUTOMAGIC KERNELS LIST"
  555.  
  556. startopt="## ## Start Default Options ##"
  557. endopt="## ## End Default Options ##"
  558.  
  559. # path to grub2
  560. grub2name="/boot/grub/core.img"
  561.  
  562. # Extract options from config file
  563. ExtractMenuOpt()
  564. {
  565.     opt=$1
  566.  
  567.     sed -ne "/^$start\$/,/^$end\$/ {
  568.         /^$startopt\$/,/^$endopt\$/ {
  569.             /^# $opt=/ {
  570.                 s/^# $opt=\(.*\)\$/\1/
  571.                 p
  572.             }
  573.         }
  574.     }" $menu
  575. }
  576.  
  577. GetMenuOpts()
  578. {
  579.     opt=$1
  580.  
  581.     sed -ne "/^$start\$/,/^$end\$/ {
  582.         /^$startopt\$/,/^$endopt\$/ {
  583.             /^# $opt=/ {
  584.                 p
  585.             }
  586.         }
  587.     }" $menu
  588. }
  589.  
  590. ExtractMenuOpts()
  591. {
  592.     opt=$1
  593.  
  594.     GetMenuOpts $opt | sed "s/^# $opt=\(.*\)\$/\1=\"\2\"/"
  595. }
  596.  
  597. GetMenuOpt()
  598. {
  599.     opt=$1
  600.     value=$2
  601.  
  602.     [ -z "$(GetMenuOpts "$opt")" ] || value=$(ExtractMenuOpt "$opt")
  603.  
  604.     echo $value
  605. }
  606.  
  607. # Compares two version strings A and B
  608. # Returns -1 if A<B
  609. #          0 if A==B
  610. #          1 if A>B
  611. # This compares version numbers of the form
  612. # 2.4.14.2 > 2.4.14
  613. # 2.4.14random = 2.4.14-random > 2.4.14-ac10 > 2.4.14 > 2.4.14-pre2 > 
  614. # 2.4.14-pre1 > 2.4.13-ac99
  615. CompareVersions()
  616. {  
  617.         #Changes the line something-x.y.z into somthing-x.y.z.q
  618.     #This is to ensure that kernels with a .q is treated as higher than the ones without               
  619.         #First a space is put after the version number
  620.         v1=$(echo $1 | sed -e 's!^\(.*-\([0-9]\+\.\)\{2,3\}[0-9]\+\)\(.*\)!\1 \3!g')
  621.     v2=$(echo $2 | sed -e 's!^\(.*-\([0-9]\+\.\)\{2,3\}[0-9]\+\)\(.*\)!\1 \3!g')
  622.     #If the version number only has 3 digits then put in another .0
  623.         v1=$(echo $v1 | sed -e 's!^\(.*-\([0-9]\+\.\)\{2\}[0-9]\+\)\( .*\|$\)!\1.0 \3!g')
  624.         v2=$(echo $v2 | sed -e 's!^\(.*-\([0-9]\+\.\)\{2\}[0-9]\+\)\( .*\|$\)!\1.0 \3!g')
  625.           
  626.     # Then split the version number and remove any '.' 's or dashes
  627.     v1=$(echo $v1 | sed -e 's![-\.]\+! !g' -e 's!\([0-9]\)\([[:alpha:]]\)!\1 \2!')
  628.     v2=$(echo $v2 | sed -e 's![-\.]\+! !g' -e 's!\([0-9]\)\([[:alpha:]]\)!\1 \2!')
  629.  
  630.     # we weight different kernel suffixes here
  631.     # ac   = 50
  632.     # pre  = -50
  633.     # rc   = -40
  634.     # test = -60
  635.     # others are given 99
  636.     v1=$(echo $v1 | sed -e 's! k7! 786 !g' -e 's! ac! 50 !g' -e 's! rc! -40 !g' -e 's! pre! -50 !g' -e 's! test! -60 !g' -e 's![^ ]*[^-0-9 ][^ ]*!99!g')
  637.  
  638.     v2=$(echo $v2 | sed -e 's! k7! 786 !g' -e 's! ac! 50 !g' -e 's! rc! -40 !g' -e 's! pre! -50 !g' -e 's! test! -60 !g' -e 's![^ ]*[^-0-9 ][^ ]*!99!g')
  639.  
  640.     result=0; v1finished=0; v2finished=0;
  641.     while [ $result -eq 0 ] && [ $v1finished -eq 0 ] && [ $v2finished -eq 0 ];
  642.     do
  643.         if [ "$v1" = "" ]; then
  644.             v1comp=0; v1finished=1
  645.         else
  646.             set -- $v1; v1comp=$1; shift; v1=$*
  647.         fi
  648.  
  649.         if [ "$v2" = "" ]; then
  650.             v2comp=0; v2finished=1
  651.         else
  652.             set -- $v2; v2comp=$1; shift; v2=$*
  653.         fi
  654.         
  655.         set +e
  656.         result=`expr $v1comp - $v2comp` 
  657.         result=`expr substr $result 1 2`
  658.         set -e
  659.  
  660.         if   [ $result -gt 0 ]; then result=1
  661.         elif [ $result -lt 0 ]; then result=-1    
  662.         fi    
  663.     done
  664.  
  665.     # finally return the result
  666.     echo $result
  667. }
  668.  
  669. # looks in the directory specified for an initrd image with the version specified
  670. FindInitrdName()
  671. {
  672.     # strip trailing slashes
  673.     directory=$(echo $1 | sed -e 's#/*$##')
  674.     version=$2
  675.  
  676.     # initrd
  677.     # initrd.img
  678.     # initrd-lvm
  679.     # .*.gz
  680.  
  681.     initrdName=""
  682.     names="initrd initrd.img initrd-lvm"
  683.     compressed="gz"
  684.  
  685.     for n in $names ; do
  686.         # make sure we haven't already found it
  687.         if [ -z "$initrdName" ] ; then
  688.             if [ -f "$directory/$n$version" ] ; then
  689.                 initrdName="$n$version"
  690.                 break
  691.             else
  692.                 for c in $compressed ; do
  693.                     if [ -f "$directory/$n$version.$c" ] ; then
  694.                         initrdName="$n$version.$c"
  695.                         break
  696.                     fi
  697.                 done
  698.             fi
  699.         else
  700.             break
  701.         fi
  702.     done
  703.  
  704.     # return the result
  705.     echo $initrdName
  706. }
  707.  
  708. FindXenHypervisorVersions ()
  709. {
  710.     version=$1
  711.  
  712.     if [ -f "/var/lib/linux-image-$version/xen-versions" ]; then
  713.         ret="$(cat /var/lib/linux-image-$version/xen-versions)"
  714.     fi
  715.  
  716.     echo $ret
  717. }
  718.  
  719. get_kernel_opt()
  720. {
  721.     kernel_version=$1
  722.  
  723.     version=$(echo $kernel_version | sed 's/^[^0-9]*//')
  724.     version=$(echo $version | sed 's/[-\+\.]/_/g')
  725.     if [ -n "$version" ] ; then
  726.         while [ -n "$version" ] ; do
  727.             currentOpt="$(eval "echo \${kopt_$version}")"
  728.             if [ -n "$currentOpt" ] ; then
  729.                 break
  730.             fi
  731.  
  732.             oldversion="$version"
  733.             version=$(echo $version | sed 's/_\?[^_]*$//')
  734.             if [ "$version" = "$oldversion" ] ; then
  735.                 # Break infinite loop, if the version isn't what we expect
  736.                 break
  737.             fi
  738.         done
  739.     fi
  740.  
  741.     if [ -z "$currentOpt" ] ; then
  742.             currentOpt=$kopt
  743.     fi
  744.  
  745.     echo $currentOpt
  746. }
  747.  
  748. write_kernel_entry()
  749. {
  750.     local kernel_version; kernel_version=$1; shift
  751.     local recovery_desc; recovery_desc=$1; shift
  752.     local lock_alternative; lock_alternative=$1; shift
  753.     local grub_root_device; grub_root_device=$1; shift
  754.     local kernel; kernel=$1; shift
  755.     local kernel_options; kernel_options=$1; shift
  756.     local recovery_suffix; recovery_suffix=$1; shift
  757.     local initrd; initrd=$1; shift
  758.     local savedefault; savedefault=$1; shift
  759.     local lockold; lockold=$1; shift
  760.     local dapper_upgrade; dapper_upgrade=$1; shift
  761.     local hypervisor
  762.     if [ -n "$1" ]; then
  763.         # Hypervisor.
  764.         hypervisor=$1; shift
  765.         local hypervisor_image; hypervisor_image=$1; shift
  766.         local hypervisor_version; hypervisor_version=$1; shift
  767.         local hypervisor_options; hypervisor_options=$1; shift
  768.     fi
  769.  
  770.     echo -n "title        " >> $buffer
  771.  
  772.     if [ -n "$hypervisor" ]; then
  773.         echo -n "$hypervisor $hypervisor_version / " >> $buffer
  774.     fi
  775.  
  776.     echo -n "$title" >> $buffer
  777.     if [ -n "$kernel_version" ]; then
  778.         echo -n ", " >> $buffer
  779.         # memtest86 is not strictly a kernel
  780.         if ! echo "$kernel_version" | grep -q ^memtest86; then
  781.             echo -n "kernel " >> $buffer
  782.         fi
  783.         echo -n "$kernel_version" >> $buffer
  784.     fi
  785.     if [ -n "$recovery_desc" ]; then
  786.         echo -n " $recovery_desc" >> $buffer
  787.     fi
  788.     echo >> $buffer
  789.  
  790.     # lock the alternative options
  791.     if test x"$lock_alternative" = x"true" ; then
  792.         echo "lock" >> $buffer
  793.     fi
  794.     # lock the old entries
  795.     if test x"$lockold" = x"true" ; then
  796.     echo "lock" >> $buffer
  797.     fi
  798.  
  799.     case "$grub_root_device" in
  800.         [^A-Za-z0-9]*)
  801.             echo "root        $grub_root_device" >> $buffer
  802.         ;;
  803.         *)
  804.             echo "uuid        $grub_root_device" >> $buffer
  805.         ;;
  806.     esac
  807.  
  808.     echo -n "kernel        "  >> $buffer
  809.     if [ -n "$hypervisor" ]; then
  810.         echo -n "$hypervisor_image" >> $buffer
  811.         if [ -n "$hypervisor_options" ]; then
  812.             echo -n " $hypervisor_options"  >> $buffer
  813.         fi
  814.         echo >> $buffer
  815.         echo -n "module        "  >> $buffer
  816.     fi
  817.     echo -n "$kernel"  >> $buffer
  818.     if [ -n "$kernel_options" ]; then
  819.         echo -n " $kernel_options"  >> $buffer
  820.     fi
  821.     if [ -n "$recovery_desc" ]; then
  822.         echo -n " $recovery_suffix"  >> $buffer
  823.     fi
  824.     if [ -n "$dapper_upgrade" -a -z "$kernel_options$recovery_desc" ]; then
  825.         echo -n " "  >> $buffer
  826.     fi
  827.     echo >> $buffer
  828.  
  829.     if [ -n "$initrd" ]; then
  830.         if [ -n "$hypervisor" ]; then
  831.             echo -n "module        " >> $buffer
  832.         else
  833.             echo -n "initrd        " >> $buffer
  834.         fi
  835.         echo "$initrd" >> $buffer
  836.     fi
  837.  
  838.     if [ ! -n "$recovery_desc" -a x"$supports_quiet" = x"true" -a -z "$dapper_upgrade" ]; then
  839.         echo "quiet" >> $buffer
  840.     fi
  841.  
  842.     if test x"$savedefault" = x"true" ; then
  843.         echo "savedefault" >> $buffer
  844.     fi
  845.     if test x"$dapper_upgrade" != x ; then
  846.         echo "boot" >> $buffer
  847.     fi
  848.     echo >> $buffer
  849. }
  850.  
  851. ## write out the kernel entries
  852. output_kernel_list() {
  853.     counter=0
  854.  
  855.     # Xen entries first.
  856.     for kern in $xenKernels ; do
  857.         if test ! x"$howmany" = x"all" ; then
  858.             if [ $counter -gt $howmany ] ; then
  859.                 break
  860.             fi
  861.         fi
  862.  
  863.         kernelName=$(basename $kern)
  864.         kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz//')
  865.  
  866.         initrdName=$(FindInitrdName "/boot" "$kernelVersion")
  867.         initrd=""
  868.  
  869.         kernel=$kernel_dir/$kernelName
  870.         if [ -n "$initrdName" ] ; then
  871.             initrd=$kernel_dir/$initrdName
  872.         fi
  873.  
  874.         kernelVersion=$(echo $kernelVersion | sed -e 's/^-//')
  875.         currentOpt=$(get_kernel_opt $kernelVersion)
  876.  
  877.         hypervisorVersions=$(FindXenHypervisorVersions "$kernelVersion")
  878.  
  879.         found=
  880.         for hypervisorVersion in $hypervisorVersions; do
  881.             hypervisor="$kernel_dir/xen-$hypervisorVersion.gz"
  882.             if [ -e "$hypervisor" ]; then
  883.                 found=1
  884.  
  885.                 echo "Found Xen hypervisor $hypervisorVersion,  kernel: $kernel" >&2
  886.  
  887.                 write_kernel_entry "$kernelVersion" '' '' "$grub_root_device" \
  888.                   "$kernel" "$currentOpt $xenkopt" '' "$initrd" "$savedefault" '' "$dapper_upgrade" \
  889.                   Xen "$hypervisor" "$hypervisorVersion" "$xenhopt"
  890.                 counter=$(($counter + 1))
  891.             fi
  892.         done
  893.  
  894.         if [ -z $found ]; then
  895.             for hypervisor in $hypervisors; do
  896.                 hypVersion=`basename "$hypervisor" .gz | sed s%xen-%%`
  897.         
  898.                 echo "Found Xen hypervisor $hypVersion,  kernel: $kernel" >&2
  899.  
  900.                 write_kernel_entry "$kernelVersion" '' '' "$grub_root_device" \
  901.                   "$kernel" "$currentOpt $xenkopt" '' "$initrd" "$savedefault" '' "$dapper_upgrade" \
  902.                   Xen "$kernel_dir/$hypervisor" "$hypVersion" "$xenhopt"
  903.                 counter=$(($counter + 1))
  904.             done
  905.         fi
  906.     done
  907.  
  908.     for kern in $sortedKernels ; do
  909.         counter=$(($counter + 1))
  910.         if test ! x"$howmany" = x"all" ; then
  911.             if [ $counter -gt $howmany ] ; then 
  912.                 break
  913.             fi
  914.         fi
  915.         kernelName=$(basename $kern)
  916.         initrdName=""
  917.         initrd=""
  918.         extra_opts=""
  919.  
  920.         if [ "$kern" = "/boot/last-good-boot/vmlinuz" ]; then
  921.             kernelVersion="Last successful boot"
  922.             if [ -e "/boot/last-good-boot/initrd.img" ]; then
  923.                 initrdName="last-good-boot/initrd.img"
  924.             fi
  925.             kernelName="last-good-boot/vmlinuz"
  926.             extra_opts="$extra_opts last-good-boot"
  927.         else
  928.             kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz//')
  929.             initrdName=$(FindInitrdName "/boot" "$kernelVersion")
  930.             if [ -x "/usr/bin/makedumpfile" ] && [ -x "/sbin/kexec" ]; then
  931.                 extra_opts="$extra_opts crashkernel=384M-2G:64M@16M,2G-:128M@16M"
  932.             fi
  933.         fi
  934.  
  935.         kernel=$kernel_dir/$kernelName
  936.  
  937.         if [ -n "$initrdName" ] ; then
  938.             initrd=$kernel_dir/$initrdName
  939.         fi
  940.  
  941.         echo "Found kernel: $kernel" >&2
  942.  
  943.         if [ "$kernelName" = "vmlinuz" ]; then
  944.             if [ -L "/boot/$kernelName" ]; then
  945.                 kernelVersion=`readlink -f "/boot/$kernelName"`
  946.                 kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//')
  947.                 kernelVersion="$kernelVersion Default"
  948.             else
  949.                 kernelVersion="Default"
  950.             fi
  951.         fi
  952.         if [ "$kernelName" = "vmlinuz.old" ]; then
  953.             if [ -L "/boot/$kernelName" ]; then
  954.                 kernelVersion=`readlink -f "/boot/$kernelName"`
  955.                 kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//')
  956.                 kernelVersion="$kernelVersion Previous"
  957.             else
  958.                 kernelVersion="Previous"
  959.             fi
  960.         fi
  961.  
  962.         kernelVersion=$(echo $kernelVersion | sed -e 's/^-//')
  963.  
  964.         currentOpt=$(get_kernel_opt $kernelVersion)
  965.  
  966.         do_lockold=$lockold
  967.         # do not lockold for the first entry
  968.         [ $counter -eq 1 ] && do_lockold=false
  969.  
  970.         if [ "$kernelName" = "last-good-boot/vmlinuz" ]; then
  971.             if [ -e /boot/last-good-boot/cmdline ]; then
  972.                 cmdline="$(cat /boot/last-good-boot/cmdline) last-good-boot"
  973.             else
  974.                 cmdline="$currentOpt $defoptions $extra_opts"
  975.             fi
  976.             write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" "$kernel" \
  977.                 "$cmdline" "" "$initrd" "$savedefault" "$do_lockold" \
  978.                 "$dapper_upgrade"
  979.         else
  980.             write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" "$kernel" \
  981.                 "$currentOpt $defoptions $extra_opts" "" "$initrd" "$savedefault" \
  982.                 "$do_lockold" "$dapper_upgrade"
  983.         fi
  984.  
  985.         # insert the alternative boot options
  986.         if test ! x"$alternative" = x"false" && \
  987.            test ! x"$kernelName" = x"last-good-boot/vmlinuz"; then
  988.             # for each altoptions line do this stuff
  989.             sed -ne 's/# altoptions=\(.*\)/\1/p' $buffer | while read line; do
  990.                 descr=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\1/p')
  991.                 suffix=$(echo $line | sed -ne 's/\(([^)]*)\)[[:space:]]\(.*\)/\2/p')
  992.  
  993.                 test x"$lockalternative" = x"true" && do_lockold=false
  994.                 write_kernel_entry "$kernelVersion" "$descr" "$lockalternative" \
  995.                     "$grub_root_device" "$kernel" "$currentOpt $extra_opts" \
  996.                     "$suffix" "$initrd" "false" "$do_lockold" \
  997.                     "$dapper_upgrade"
  998.             done
  999.         fi
  1000.     done
  1001.  
  1002.     if test -f $grub2name ; then
  1003.         echo "Found GRUB 2: $grub2name" >&2
  1004.         cat >> $buffer << EOF
  1005. title        Chainload into GRUB 2
  1006. root        $grub_root_device
  1007. kernel        $grub2name
  1008. EOF
  1009.         if test x"$savedefault" = x"true" ; then
  1010.             echo "savedefault" >> $buffer
  1011.         fi
  1012.         echo >> $buffer
  1013.     fi
  1014.     
  1015.     memtest86names="memtest86 memtest86+"
  1016.  
  1017.     if test ! x"$memtest86" = x"false" ; then
  1018.         for name in $memtest86names ; do
  1019.             if test -f "/boot/$name.bin" ; then
  1020.                 kernelVersion="$name"
  1021.                 kernel="$kernel_dir/$name.bin"
  1022.                 currentOpt=
  1023.                 initrd=
  1024.  
  1025.                 echo "Found kernel: $kernel" >&2
  1026.  
  1027.                 write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" \
  1028.                 "$kernel" "$currentOpt" "" "$initrd" "false" "" "$dapper_upgrade"
  1029.             fi
  1030.         done
  1031.     fi
  1032.  
  1033.     echo $end >> $buffer
  1034. }
  1035.  
  1036. ucf_update_kernels() {
  1037.     local target; target="$1"
  1038.     local buffer; buffer="$2"
  1039.  
  1040.     sed -ni -e"/$endopt/,/$end/p" "$buffer"
  1041.  
  1042.     if [ "x$initialconfig" = "x" ]; then
  1043.         sed -n -e"/$endopt/,/$end/p" < $menu > $ucf_menu_file
  1044.     else
  1045.         cat $buffer > $ucf_menu_file
  1046.     fi
  1047.  
  1048.     db_x_loadtemplatefile /var/lib/dpkg/info/grub.templates grub
  1049.  
  1050.     ucf --debconf-ok \
  1051.         --debconf-template grub/update_grub_changeprompt_threeway \
  1052.         --three-way "$buffer" $ucf_menu_file
  1053.     rm "$buffer"
  1054.  
  1055.     # now re-merge the ucf results with the target file
  1056.     sed -i -e "/^$endopt/,/^$end/ {
  1057.         /^$endopt/r $ucf_menu_file
  1058.         d
  1059.     }
  1060.     " $target
  1061.  
  1062.     rm -f $ucf_menu_file ${ucf_menu_file}.ucf-old
  1063. }
  1064.  
  1065.  
  1066. echo -n "Testing for an existing GRUB $menu_file_basename file ... " >&2
  1067.  
  1068. # Test if our menu file exists
  1069. if [ -f "$menu_file" ] ; then
  1070.     menu="$menu_file"
  1071.     rm -f $newtemplate
  1072.     unset newtemplate
  1073.     echo "found: $menu_file" >&2
  1074.     cp -f "$menu_file" "$menu_file~"
  1075. else
  1076.     # if not ask user if they want us to create one
  1077.     initialconfig=1
  1078.     menu="$menu_file"
  1079.     echo >&2
  1080.     echo >&2
  1081.     echo -n "Could not find $menu_file file. " >&2
  1082.     if [ "-y" = "$command_line_arguments" ] ; then
  1083.         echo >&2
  1084.         echo "Generating $menu_file" >&2
  1085.         answer=y
  1086.     else
  1087.         echo -n "Would you like $menu_file generated for you? " >&2
  1088.         echo -n "(y/N) " >&2
  1089.         read answer <&2
  1090.     fi
  1091.  
  1092.     case "$answer" in
  1093.         y* | Y*)
  1094.         cat "$newtemplate" > $menu_file
  1095.         rm -f $newtemplate
  1096.         unset newtemplate
  1097.         ;;
  1098.         *)
  1099.         abort "Not creating $menu_file as you wish"
  1100.         ;;
  1101.     esac
  1102. fi
  1103.  
  1104. # Extract the kernel options to use
  1105. kopt=$(GetMenuOpt "kopt" "$kopt")
  1106.  
  1107. # Extract options for specific kernels
  1108. opts="$(ExtractMenuOpts "\(kopt_[[:alnum:]_]\+\)")"
  1109. test -z "$opts" || eval "$opts"
  1110. CustomKopts=$(GetMenuOpts "\(kopt_[[:alnum:]_]\+\)" | \
  1111.     grep -v "^# kopt_2_6=" || true)
  1112.  
  1113. # Set the kernel 2.6 option only for fresh install (but convert it to
  1114. # mount-by-UUID on upgrade)
  1115. test -z "$kopt_2_6" && test -z "$(GetMenuOpt "kopt" "")" && \
  1116.     kopt_2_6="$default_kopt"
  1117.  
  1118. # Extract the grub root
  1119. grub_root_device=$(GetMenuOpt "groot" "$grub_root_device")
  1120.  
  1121. # Extract the old recovery value
  1122. alternative=$(GetMenuOpt "recovery" "$alternative")
  1123.  
  1124. # Extract the alternative value
  1125. alternative=$(GetMenuOpt "alternative" "$alternative")
  1126.  
  1127. # Extract the lockalternative value
  1128. lockalternative=$(GetMenuOpt "lockalternative" "$lockalternative")
  1129.  
  1130. # Extract the additional default options
  1131. # Check nonaltoptions too for compatibility with Ubuntu <= 5.10
  1132. defoptions=$(GetMenuOpt "nonaltoptions" "$defoptions")
  1133. defoptions=$(GetMenuOpt "defoptions" "$defoptions")
  1134.  
  1135. # Extract the lockold value
  1136. lockold=$(GetMenuOpt "lockold" "$lockold")
  1137.  
  1138. # Extract Xen hypervisor options
  1139. xenhopt=$(GetMenuOpt "xenhopt" "$xenhopt")
  1140.  
  1141. # Extract Xen Linux kernel options
  1142. xenkopt=$(GetMenuOpt "xenkopt" "$xenkopt")
  1143.  
  1144. # Extract the howmany value
  1145. howmany=$(GetMenuOpt "howmany" "$howmany")
  1146.  
  1147. # Extract the memtest86 value
  1148. memtest86=$(GetMenuOpt "memtest86" "$memtest86")
  1149.  
  1150. # Extract the indomU value
  1151. indomU=$(GetMenuOpt "indomU" "$indomU")
  1152.  
  1153. # Extract the updatedefaultentry option
  1154. updatedefaultentry=$(GetMenuOpt "updatedefaultentry" "$updatedefaultentry")
  1155.  
  1156. # If "default saved" is in use, set the default to true
  1157. grep -q "^default.*saved" $menu && savedefault=true
  1158. # Extract the savedefault option
  1159. savedefault=$(GetMenuOpt "savedefault" "$savedefault")
  1160.  
  1161. # Generate the menu options we want to insert
  1162. buffer=$(tempfile)
  1163. echo $start >> $buffer
  1164. echo "## lines between the AUTOMAGIC KERNELS LIST markers will be modified" >> $buffer
  1165. echo "## by the debian update-grub script except for the default options below" >> $buffer
  1166. echo >> $buffer
  1167. echo "## DO NOT UNCOMMENT THEM, Just edit them to your needs" >> $buffer
  1168. echo >> $buffer
  1169. echo "## ## Start Default Options ##" >> $buffer
  1170.  
  1171. echo "## default kernel options" >> $buffer
  1172. echo "## default kernel options for automagic boot options" >> $buffer
  1173. echo "## If you want special options for specific kernels use kopt_x_y_z" >> $buffer
  1174. echo "## where x.y.z is kernel version. Minor versions can be omitted." >> $buffer
  1175. echo "## e.g. kopt=root=/dev/hda1 ro" >> $buffer
  1176. echo "##      kopt_2_6_8=root=/dev/hdc1 ro" >> $buffer
  1177. echo "##      kopt_2_6_8_2_686=root=/dev/hdc2 ro" >> $buffer
  1178. echo "# kopt=$kopt" >> $buffer
  1179. if [ -n "$kopt_2_6" ] && [ "$kopt" != "$kopt_2_6" ]; then
  1180.     echo "# kopt_2_6=$kopt_2_6" >> $buffer
  1181. fi
  1182. if [ -n "$CustomKopts" ] ; then
  1183.     echo "$CustomKopts" >> $buffer
  1184. fi
  1185. echo >> $buffer
  1186.  
  1187. echo "## default grub root device" >> $buffer
  1188. echo "## e.g. groot=(hd0,0)" >> $buffer
  1189. echo "# groot=$grub_root_device" >> $buffer
  1190. echo >> $buffer
  1191.  
  1192. echo "## should update-grub create alternative automagic boot options" >> $buffer
  1193. echo "## e.g. alternative=true" >> $buffer
  1194. echo "##      alternative=false" >> $buffer
  1195. echo "# alternative=$alternative" >> $buffer
  1196. echo >> $buffer
  1197.  
  1198. echo "## should update-grub lock alternative automagic boot options" >> $buffer
  1199. echo "## e.g. lockalternative=true" >> $buffer
  1200. echo "##      lockalternative=false" >> $buffer
  1201. echo "# lockalternative=$lockalternative" >> $buffer
  1202. echo >> $buffer
  1203.  
  1204. echo "## additional options to use with the default boot option, but not with the" >> $buffer
  1205. echo "## alternatives" >> $buffer
  1206. echo "## e.g. defoptions=vga=791 resume=/dev/hda5" >> $buffer
  1207. echo "# defoptions=$defoptions" >> $buffer
  1208. echo >> $buffer
  1209.  
  1210. echo "## should update-grub lock old automagic boot options" >> $buffer
  1211. echo "## e.g. lockold=false" >> $buffer
  1212. echo "##      lockold=true" >> $buffer
  1213. echo "# lockold=$lockold" >> $buffer
  1214. echo >> $buffer
  1215.  
  1216. echo "## Xen hypervisor options to use with the default Xen boot option" >> $buffer
  1217. echo "# xenhopt=$xenhopt" >> $buffer
  1218. echo >> $buffer
  1219.  
  1220. echo "## Xen Linux kernel options to use with the default Xen boot option" >> $buffer
  1221. echo "# xenkopt=$xenkopt" >> $buffer
  1222. echo >> $buffer
  1223.  
  1224. echo "## altoption boot targets option" >> $buffer
  1225. echo "## multiple altoptions lines are allowed" >> $buffer
  1226. echo "## e.g. altoptions=(extra menu suffix) extra boot options" >> $buffer
  1227. echo "##      altoptions=(recovery) single" >> $buffer
  1228.  
  1229. if ! grep -q "^# altoptions" $menu ; then
  1230.     echo "# altoptions=$altoptions" >> $buffer
  1231. else
  1232.     grep "^# altoptions" $menu >> $buffer
  1233. fi
  1234. echo >> $buffer
  1235.  
  1236. echo "## controls how many kernels should be put into the $menu_file_basename" >> $buffer
  1237. echo "## only counts the first occurence of a kernel, not the" >> $buffer
  1238. echo "## alternative kernel options" >> $buffer
  1239. echo "## e.g. howmany=all" >> $buffer
  1240. echo "##      howmany=7" >> $buffer
  1241. echo "# howmany=$howmany" >> $buffer
  1242. echo >> $buffer
  1243.  
  1244. echo "## specify if running in Xen domU or have grub detect automatically" >> $buffer
  1245. echo "## update-grub will ignore non-xen kernels when running in domU and vice versa" >> $buffer
  1246. echo "## e.g. indomU=detect" >> $buffer
  1247. echo "##      indomU=true" >> $buffer
  1248. echo "##      indomU=false" >> $buffer
  1249. echo "# indomU=$indomU" >> $buffer
  1250. echo >> $buffer
  1251.  
  1252. echo "## should update-grub create memtest86 boot option" >> $buffer
  1253. echo "## e.g. memtest86=true" >> $buffer
  1254. echo "##      memtest86=false" >> $buffer
  1255. echo "# memtest86=$memtest86" >> $buffer
  1256. echo >> $buffer
  1257.  
  1258. echo "## should update-grub adjust the value of the default booted system" >> $buffer
  1259. echo "## can be true or false" >> $buffer
  1260. echo "# updatedefaultentry=$updatedefaultentry" >> $buffer
  1261. echo >> $buffer
  1262.  
  1263. echo "## should update-grub add savedefault to the default options" >> $buffer
  1264. echo "## can be true or false" >> $buffer
  1265. echo "# savedefault=$savedefault" >> $buffer
  1266. echo >> $buffer
  1267.  
  1268. echo "## ## End Default Options ##" >> $buffer
  1269. echo >> $buffer
  1270.  
  1271. echo -n "Searching for splash image ... " >&2
  1272. current_splash=`grep '^splashimage=' ${menu_file} || true`
  1273. splash_root_device=""
  1274. splash_uuid=""
  1275. case "$grub_root_device" in
  1276.     [^A-Za-z0-9]*)
  1277.         splash_root_device=${grub_root_device}
  1278.     ;;
  1279.     *)
  1280.         splash_uuid="uuid        $grub_root_device"
  1281.     ;;
  1282. esac
  1283. splashimage_path="splashimage=${splash_root_device}${grub_dir##${boot_device:+/boot}}/splash.xpm.gz"
  1284. if [ `sed -e "/^$start/,/^$end/d" $menu_file | grep -c '^splashimage='` != "0" ] ; then
  1285.        #checks for splashscreen defined outside the autoupdated part
  1286.        splashimage=$(grep '^splashimage=' ${menu_file})
  1287.        echo "found: ${splashimage##*=}" >&2
  1288.        echo >&2  
  1289. elif [ -f "${grub_dir}/splash.xpm.gz" ]  && [ "$current_splash" = "" ]; then
  1290.        echo "found: /boot/grub/splash.xpm.gz" >&2
  1291.        echo "$splash_uuid" >> $buffer
  1292.        echo "$splashimage_path" >> $buffer
  1293.        echo >> $buffer
  1294. elif [ -f "${grub_dir}/splash.xpm.gz" ]  && [ "$current_splash" = "$splashimage_path" ]; then
  1295.        echo "found: /boot/grub/splash.xpm.gz" >&2
  1296.        echo "$splash_uuid" >> $buffer
  1297.        echo "$splashimage_path" >> $buffer
  1298.        echo >> $buffer
  1299. elif [ "$current_splash" != "" ] && [ "$current_splash" != "$splashimage_path" ]; then
  1300.        echo "found but preserving previous setting: $(grep '^splashimage=' ${menu_file})" >&2
  1301.        echo "$splash_uuid" >> $buffer
  1302.        echo "$current_splash" >> $buffer
  1303.        echo >> $buffer
  1304. else
  1305.        echo "none found, skipping ..." >&2
  1306. fi
  1307.  
  1308.  
  1309. hypervisors=""
  1310. for hyp in /boot/xen-*.gz; do
  1311.     if [ ! -h "$hyp" ] && [ -f "$hyp" ]; then
  1312.     hypervisors="$hypervisors `basename "$hyp"`"
  1313.     fi
  1314. done
  1315.  
  1316. # figure out where grub looks for the kernels at boot time
  1317. kernel_dir=/boot
  1318. if [ -n "$boot_device" ] ; then
  1319.     kernel_dir=
  1320. fi
  1321.  
  1322.  
  1323. # We need a static path to use for the ucf registration; since we're not
  1324. # using the full menu.lst file (maybe we should, just copying it around?
  1325. # C.f. discussion with Manoj), create a directory in a fixed location
  1326. # even though we're not treating the file in that location as
  1327. # persistent.
  1328. mkdir -p /var/run/grub
  1329.  
  1330. # The first time ucf sees the file, we can only assume any difference
  1331. # between the magic comments and the kernel options is a result of local
  1332. # mods, so this will result in a ucf prompt for anyone whose first
  1333. # invocation of update-grub is as a result of updating the magic comments.
  1334. if ! ucfq grub | grep -q $ucf_menu_file; then
  1335.     otherbuffer=$(tempfile)
  1336.     cat $buffer > $otherbuffer
  1337.  
  1338.     sortedKernels=`sed -n -e "
  1339.     /$endopt/,/$end/ {
  1340.         s/^kernel[[:space:]]\+\([^[:space:]]\+\).*/\1/p
  1341.     }" < $menu | grep -vE "memtest86|$grub2name|xen" | uniq`
  1342.     xenKernels=`sed -n -e "
  1343.     /$endopt/,/$end/ {
  1344.         s/^module[[:space:]]\+\([^[:space:]]*vmlinuz[^[:space:]]\+\).*/\1/p
  1345.     }" < $menu | uniq`
  1346.  
  1347.     savebuffer="$buffer"
  1348.     buffer="$otherbuffer"
  1349.     savetitle="$title"
  1350.     title="$(sed -n -e "/$endopt/,/$end/ {
  1351.         s/^title[[:space:]]\+\(.*\),.*/\1/p
  1352.     }" < $menu | head -n 1)"
  1353.     if [ -z "$title" ]; then
  1354.         title="$savetitle"
  1355.     fi
  1356.  
  1357.     # Hack: the kernel list output in Ubuntu 6.06 was different than
  1358.     # in the current version, so to support smooth upgrades we need to
  1359.     # properly detect a config generated by this old version of
  1360.     # update-grub and mimic it for the initial ucf registration
  1361.     dapper_upgrade=`sed -n -e "
  1362.     /$endopt/,/$end/ {
  1363.         /^boot/p
  1364.     }" < $menu`
  1365.     save_savedefault="$savedefault"
  1366.     if [ -n "$dapper_upgrade" ]; then
  1367.         savedefault=true
  1368.     fi
  1369.  
  1370.     output_kernel_list
  1371.  
  1372.     savedefault="$save_savedefault"
  1373.     dapper_upgrade=""
  1374.     buffer="$savebuffer"
  1375.     title="$savetitle"
  1376.  
  1377.     ucf_update_kernels "$menu" "$otherbuffer"
  1378.  
  1379.     # all done, now register it
  1380.     ucfr grub $ucf_menu_file
  1381. fi
  1382.  
  1383.  
  1384. xenKernels=""
  1385. for ver in `grep -l CONFIG_XEN_PRIVILEGED_GUEST=y /boot/config* | sed -e s%/boot/config-%%`; do
  1386.   # ver is a kernel version
  1387.   kern="/boot/vmlinuz-$ver"
  1388.   if [ -r $kern ] ; then
  1389.        newerKernels=""
  1390.        for i in $xenKernels ; do
  1391.                 res=$(CompareVersions "$kern" "$i")
  1392.                 if [ "$kern" != "" ] && [ "$res" -gt 0 ] ; then
  1393.                         newerKernels="$newerKernels $kern $i"
  1394.                         kern=""
  1395.                 else
  1396.                         newerKernels="$newerKernels $i"
  1397.                 fi
  1398.         done
  1399.         if [ "$kern" != "" ] ; then
  1400.                 newerKernels="$newerKernels $kern"
  1401.         fi
  1402.         xenKernels="$newerKernels"
  1403.     fi
  1404. done
  1405.  
  1406. if [ "$indomU" = "detect" ]; then
  1407.     if [ -e /proc/xen/capabilities ] && ! grep -q "control_d" /proc/xen/capabilities; then
  1408.         indomU="true"
  1409.     else
  1410.         indomU="false"
  1411.     fi
  1412. fi
  1413.  
  1414. sortedKernels=""
  1415. for kern in $(/bin/ls -1vr /boot | grep -v "dpkg-*" | grep "^vmlinuz-") ; do
  1416.     if `echo "$xenKernels" | grep -q "$kern "` || `echo "$kern" | grep -q "xen"`; then
  1417.         is_xen=1
  1418.     else
  1419.         is_xen=
  1420.     fi
  1421.  
  1422.     if [ "$indomU" = "false" ] && [ "$is_xen" ]; then
  1423.         # We aren't running in a Xen domU, skip xen kernels
  1424.         echo "Ignoring Xen kernel on non-Xen host: $kern"
  1425.         continue
  1426.     elif [ "$indomU" = "true" ] && ! [ "$is_xen" ]; then
  1427.         # We are running in a Xen domU, skip non-xen kernels
  1428.         echo "Ignoring non-Xen Kernel on Xen domU host: $kern"
  1429.         continue
  1430.     fi
  1431.     
  1432.     kern="/boot/$kern"
  1433.     newerKernels=""
  1434.     for i in $sortedKernels ; do
  1435.         res=$(CompareVersions "$kern" "$i")
  1436.         if [ "$kern" != "" ] && [ "$res" -gt 0 ] ; then
  1437.         newerKernels="$newerKernels $kern $i"
  1438.          kern=""
  1439.         else
  1440.         newerKernels="$newerKernels $i"
  1441.         fi
  1442.     done
  1443.     if [ "$kern" != "" ] ; then
  1444.         newerKernels="$newerKernels $kern"
  1445.     fi
  1446.     sortedKernels="$newerKernels"
  1447. done
  1448.  
  1449. if test -f "/boot/vmlinuz.old" ; then
  1450.     sortedKernels="/boot/vmlinuz.old $sortedKernels"
  1451. fi
  1452. if test -f "/boot/vmlinuz" ; then
  1453.     sortedKernels="/boot/vmlinuz $sortedKernels"
  1454. fi
  1455.  
  1456. # Add our last-good-boot kernel, second in list. We always add it, because
  1457. # it can appear out of nowhere.
  1458. newerKernels=""
  1459. last_good="/boot/last-good-boot/vmlinuz"
  1460. if [ -e "$last_good" ]; then
  1461.     for i in $sortedKernels ; do
  1462.         if [ "$last_good" != "" ]; then
  1463.             newerKernels="$i $last_good"
  1464.             last_good=""
  1465.         else
  1466.             newerKernels="$newerKernels $i"
  1467.         fi
  1468.     done
  1469.     # Shouldn't happen, unless someone removed all the kernels
  1470.     if [ "$last_good" != "" ]; then
  1471.         newerKernels="$newerKernels $last_good"
  1472.     fi
  1473.     sortedKernels="$newerKernels"
  1474. fi
  1475.  
  1476. #Finding the value the default line
  1477. use_grub_set_default="false"
  1478. if test "$updatedefaultentry" = "true" ; then
  1479.     defaultEntryNumber=$(sed -ne 's/^[[:blank:]]*default[[:blank:]]*\(.*\).*/\1/p' $menu)
  1480.  
  1481.     if [ "$defaultEntryNumber" = "saved" ] ; then
  1482.         defaultEntryNumber=$(sed 'q' "$grub_dir/default")
  1483.         use_grub_set_default="true"       
  1484.     fi
  1485.     
  1486.     if test -n "$defaultEntryNumber"; then    
  1487.         defaultEntryNumberPlusOne=$(expr $defaultEntryNumber \+ 1);
  1488.         defaultEntry=$(grep "^[[:blank:]]*title" $menu | sed -ne "${defaultEntryNumberPlusOne}p" | sed -ne ";s/^[[:blank:]]*title[[:blank:]]*//p")
  1489.         defaultEntry=$(echo $defaultEntry | sed -e "s/[[:blank:]]*$//") # don't trust trailing blanks    
  1490.     else
  1491.         notChangeDefault="yes"
  1492.     fi
  1493. else
  1494.         notChangeDefault="yes"
  1495. fi
  1496.  
  1497. output_kernel_list
  1498.  
  1499. otherbuffer=$(tempfile)
  1500. cat $buffer > $otherbuffer
  1501.  
  1502. ucf_update_kernels "$buffer" "$otherbuffer"
  1503.  
  1504. echo -n "Updating $menu ... " >&2
  1505. # Insert the new options into the menu
  1506. if ! grep -q "^$start" $menu ; then
  1507.     cat $buffer >> $menu
  1508.     rm -f $buffer
  1509. else
  1510.     umask 077
  1511.     sed -e "/^$start/,/^$end/{
  1512.     /^$start/r $buffer
  1513.     d
  1514.     }
  1515.     " $menu > $menu.new
  1516.     cat $menu.new > $menu
  1517.     rm -f $buffer $menu.new
  1518. fi
  1519.  
  1520. # Function to update the default value
  1521. set_default_value() {
  1522.     if [ "$use_grub_set_default" = "true" ] ; then
  1523.     grub-set-default $1
  1524.     else
  1525.     value="$1"
  1526.     newmenu=$(tempfile)
  1527.     sed -e "s/^[[:blank:]]*default[[:blank:]]*[[:digit:]]*\(.*\)/default         ${value}\1/;b" $menu > $newmenu
  1528.     cat $newmenu > $menu
  1529.     rm -f $newmenu
  1530.     unset newmenu
  1531.     fi
  1532. }
  1533.  
  1534. #Updating the default number
  1535. if test -z "$notChangeDefault"; then
  1536.     newDefaultNumberPlusOne=$(grep "^[[:blank:]]*title[[:blank:]]*" $menu | grep -n "${defaultEntry}" | cut -f1 -d ":" | sed -ne "1p")
  1537.     if test -z "$newDefaultNumberPlusOne"; then
  1538.         echo "Previous default entry removed, resetting to 0">&2
  1539.         set_default_value "0"
  1540.     elif test -z "$defaultEntry"; then
  1541.         echo "Value of default value matches no entry, resetting to 0" >&2
  1542.         set_default_value "0"
  1543.     else
  1544.         if test "$newDefaultNumberPlusOne" = "1"; then
  1545.             newDefaultNumber="0"
  1546.         else
  1547.             newDefaultNumber=$(expr $newDefaultNumberPlusOne - 1)
  1548.         fi
  1549.         echo "Updating the default booting kernel">&2
  1550.         set_default_value "$newDefaultNumber"
  1551.     fi
  1552. fi
  1553.  
  1554. echo "done" >&2
  1555. echo >&2
  1556.